package Air_war;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Arrays;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
//窗口类
public class World extends JPanel {
    public static final int WIDTH = 400;//窗口宽的常量
    public static final int HEIGHT = 700;//窗口高的常量

    public static final int START = 0;//启动状态
    public static final int RUNNING = 1;//运行状态
    public static final int  PAUSE = 2;//暂停状态
    public static final int  GAME_OVER = 3;//游戏结束状态
    private int state = START;//当前模式(默认为启动状态

    //私有化
    private Sky sky = new Sky();//天空
    private Hero hero = new Hero();//英雄机
    private Bullet[] bullets = {};//子弹
    private FlyingObject[] enemies = {};//敌机组合数组
    //敌人入场
    public FlyingObject nextOne(){
        Random rand = new Random();//随机数对象
        int type = rand.nextInt(20);
        if (type<10){//0~3刷新小蜜蜂
            return new Bee();
        }else if (type<13){//4~12刷新小敌机
            return new Airplane();
        }else{//13~19刷新大敌机
            return new BigAirplane();
        }
    }
    private int enterIndex = 0;//敌人入场计数
    //敌人入场
    public void enterAction(){
        enterIndex++;
        if (enterIndex%10==0){
            FlyingObject obj = nextOne();
            enemies = Arrays.copyOf(enemies,enemies.length+1);//扩容
            enemies[enemies.length-1] = obj;//将obj添加到最后一个元素上
        }
    }
    private int shootIndex = 0;
    //子弹入场
    public void shootAction() {
        shootIndex++;
        if (shootIndex % 10 == 0) {
            Bullet[] bs = hero.shoot();//获取子弹数组对象
            bullets = Arrays.copyOf(bullets, bullets.length + bs.length);//扩容  bs有几个就扩容几个
            System.arraycopy(bs, 0, bullets, bullets.length - bs.length, bs.length);//数组追加
        }
    }
    //移动
    public void stepAction(){
        sky.step();//天空移动
        for (int i = 0; i <enemies.length ; i++) {//遍历
            enemies[i].step();//敌人移动
        }
        for (int i = 0; i <bullets.length ; i++) {//遍历
            bullets[i].step();//子弹动
        }
    }
    //删除越界的敌人和子弹
    public void outOfBoundsAction(){
        for (int i = 0; i <enemies.length ; i++) {//遍历敌人
            if (enemies[i].isOutOfbounds()) {//判断越界
                enemies[i] = enemies[enemies.length - 1];//越界元素用最后一个元素替换
                enemies = Arrays.copyOf(enemies, enemies.length - 1);//缩容
            }
        }
            for (int j = 0; j <bullets.length ; j++) {//遍历子弹
                if (bullets[j].isOutOfbounds()){//判断越界
                    bullets[j] = bullets[bullets.length-1];//越界元素用最后一个元素替换
                    bullets = Arrays.copyOf(bullets,bullets.length-1);//缩容
                }
            }
    }
    private int score = 0 ;//玩家的得分
    public void bulletsBangAction(){
        for (int i = 0; i <bullets.length ; i++) {//遍历子弹
            Bullet b = bullets[i];//获取每一个子弹
            for (int j = 0; j <enemies.length ; j++) {//遍历敌人
                FlyingObject f = enemies[j];//获取每一个敌人
                if (b.isLive() && f.isLive() && f.isHit(b)){//若都或者   并且都撞上了
                    b.goDead();//子弹去死
                    f.goDead();//敌人去死

                    if (f instanceof EnemyScore){//若敌人被撞能得分
                        EnemyScore es = (EnemyScore)f;//则强行转换为得分结果
                        score += es.getScore();//玩家得分
                    }
                    if (f instanceof  EnemyAward){//若被撞敌人获得奖励
                        EnemyAward ea = (EnemyAward)f;//则强行转换为奖励接口
                        int type = ea.getAwardType();//获取奖励类型
                        switch (type){
                            case EnemyAward.FIRE:
                                hero.addFire();//英雄机获得火力
                                break;
                            case EnemyAward.LIFE://英雄机获得生命
                                hero.addLife();
                                break;
                        }
                    }
                }
            }
        }
    }
    //英雄机与敌人碰撞
    public void heroBangAction(){
        for (int i = 0; i <enemies.length ; i++) {//遍历敌人
            FlyingObject f = enemies[i];//获取每一个敌人
            if (hero.isLive() && f.isLive() && f.isHit(hero)){//如果都活着  并且都撞上了
                f.goDead();//敌人去死
                hero.subtractLife();//英雄机减少生命值
                hero.clearFire();//英雄机清空火力值
            }
        }
    }
    //检测游戏结束
    public void checkGameOverAction(){
        if (hero.getLife()<=0){//若英雄机生命值<=0时表示游戏结束了
            state = GAME_OVER;//则当前状态修改为游戏结束
        }
    }
    //启动程序的执行
    public void action(){
        //侦听器对象
        MouseAdapter m = new MouseAdapter() {
            //重写   鼠标移动事件
            public void mouseMoved(MouseEvent e) {
                if (state ==RUNNING){//仅在运行状态下执行
                    int x = e.getX();//获取鼠标的x位置
                    int y = e.getY();//获取鼠标的y位置
                    hero.moveTo(x,y);//英雄机跟随鼠标x，y移动
                }

            }
            //重写mouseClicked鼠标点击事件
            public void mouseClicked(MouseEvent e) {
                switch (state){//根据当前状态做不同的处理
                    case START://启动状态时
                        state = RUNNING;//修改为运行状态
                        break;
                    case GAME_OVER://游戏结束时
                        //清理现场  全部归零
                        score = 0;
                        sky = new Sky();
                        hero = new Hero();
                        enemies = new FlyingObject[0];
                        bullets = new Bullet[0];
                        state = START;//修改为游戏开始
                        break;
                }
            }
            //重写mouseexited鼠标移出事件
            public void mouseexited(MouseEvent e){
                if (state == PAUSE){//暂停状态时
                    state = RUNNING;//修改为运行状态
                }
            }
            //重写mouseentered鼠标移入事件
            public void mouseentered(MouseEvent e){
                if (state ==PAUSE){//暂停状态时
                    state =RUNNING;//修改为运行状态
                }
            }
        };
        this.addMouseListener(m);//装侦听
        this.addMouseMotionListener(m);//装侦听

        Timer timer = new Timer();//定时器间隔
        int interevel = 10;//定时间隔  十毫秒
        timer.schedule(new TimerTask() {
            public void run() {//定时干的事情  十毫秒走一次
                if (state == RUNNING){//仅在运行状态下执行
                    enterAction();//敌人进场
                    shootAction();//子弹进场
                    stepAction();//飞行物入场
                    outOfBoundsAction();//删除越界的敌人和子弹
                    bulletsBangAction();//子弹与敌人碰撞
                    heroBangAction();//英雄机与敌人碰撞
                    checkGameOverAction();//检测游戏结束
                }

                repaint();;//重画

            }
        },interevel,interevel);//定时计划表
    }
    //重写paint（）画   g：画笔
    public void paint(Graphics g){
        g.drawImage(sky.getImage(),sky.x,sky.y,null);//画天空
        g.drawImage(sky.getImage(),sky.x,sky.getY1(),null);//画天空第二章
        //g.drawImage(hero.getImage(),hero.x,hero.y,null);//画英雄机
        g.drawImage(hero.getImage(),hero.x,hero.y,null);
        for (int i = 0; i <enemies.length; i++) {//便利每一个子弹
            FlyingObject f = enemies[i];
            g.drawImage(f.getImage(),f.x,f.y,null);
        }

        for (int i = 0; i <bullets.length; i++) {//便利每一个子弹
            Bullet b = bullets[i];//获取每一个子弹
            g.drawImage(b.getImage(),b.x,b.y,null);
        }
        //分数和生命数量   显示在频幕上       坐标参数
        g.drawString("SCORE:"+score,10,25);
        g.drawString("LIFE:"+hero.getLife(),10,45);

        switch (state){
            case START://启动状态画启动图
                g.drawImage(Images.start,0,0,null);
                break;
            case PAUSE://暂停状态画暂停图
                g.drawImage(Images.pause,0,0,null);
                break;
            case GAME_OVER://游戏结束状态画游戏结束图
                g.drawImage(Images.gameover,0,0,null);
                break;
        }
    }

    public static void main(String[] args) {
        World world = new World();

        JFrame frame = new JFrame();
        frame.add(world);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(WIDTH,HEIGHT);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);//设置窗口可见  尽快调用paint方法

        world.action();//启动程序的打开
    }



}
